#ifndef xpack_io_private_handler_info
#define xpack_io_private_handler_info
#pragma push_macro("xuser")
#undef  xuser
#define xuser mixc::io_private_handler_info::inc
#include"concurrency/lock/atom_load.hpp"
#include"concurrency/lock/atom_swap.hpp"
#include"configure/limit.hpp"
#include"define/base_type.hpp"
#include"macro/xexport.hpp"
#include"utils/memory.hpp"
#pragma pop_macro("xuser")

namespace mixc::io_private_handler_info{
    inline u64 g_handler_info_list[inc::limit::max_handler];
}

namespace mixc::io_private_handler_info::origin{
    union handler_info{
        using the_t = handler_info;

        struct{
            u32 ip;
            u16 port;
            u08 type;
        } sock;

        struct{
            u64          : 52;
            u64 bytes    : 11;
            u64 is_ptr   : 1;
        };

        void store(ixx fd){
            auto other      = uxxp(& g_handler_info_list[fd]);
            auto old        = handler_info{};
            auto old_ptr    = uxxp(& old);

            for(uxx i = 0; i < sizeof(handler_info) / sizeof(uxx); i++){
                old_ptr[i]  = inc::atom_swap(uxxp(other) + i, (uxxp(this))[i]);
            }

            if (old.is_ptr){
                inc::memory::free(voidp(old.ptr), inc::memory::size(old.bytes));
            }
        }

        handler_info load(ixx fd){
            auto ptr        = uxxp(this);

            for(uxx i = 0; i < sizeof(handler_info) / sizeof(uxx); i++){
                ptr[i]      = inc::atom_load(uxxp(& g_handler_info_list[fd]) + i);
            }
            return *this;
        }

        union{
        public:
            void operator=(voidp value){
                this->value = value;
                xthe.is_ptr = 1;
            }

            operator voidp() const {
                the_t temp = xthe;
                temp.is_ptr = 0;
                return temp.ptr.value;
            }
        private:
            voidp value;
        } ptr;
    };

    static_assert(sizeof(handler_info) == sizeof(g_handler_info_list[0]));
}

#endif

xexport_space(mixc::io_private_handler_info::origin)